﻿#region Copyright information
// 
// Copyright © 2005-2013 Yongkee Cho. All rights reserved.
// 
// This code is a part of the Biological Object Library and governed under the terms of the
// GNU Lesser General  Public License (LGPL) version 2.1 which accompanies this distribution.
// For more information on the LGPL, please visit http://bol.codeplex.com/license.
// 
// - Filename: Interaction.cs
// - Author: Yongkee Cho
// - Email: yongkeecho@gmail.com
// - Date Created: 2013-01-25 3:25 PM
// - Last Modified: 2013-01-25 3:59 PM
// 
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using BOL.Algorithms.Graph;

namespace BOL.Models.MolecularInteractions
{
    /// <summary>
    /// Represent a relation.
    /// </summary>
    public class Interaction : EdgeBase<IInteractor>, ICloneable, IEquatable<Interaction>, IDbXreferable
    {
        #region Public property

        public double Confidence { get; private set; }

        public IEnumerable<DbXref> DbXrefs { get; private set; }

        public InteractionType InteractionType { get; private set; }

        public ExperimentType ExperimentType { get; private set; }

        #endregion

        #region Constructors

        public Interaction(IInteractor interactor1, IInteractor interactor2, double confidence, IEnumerable<DbXref> dbXrefs, InteractionType interactionType = InteractionType.Unknown, ExperimentType experimentType = ExperimentType.Unknown)
            : base(interactor1, interactor2)
        {
            if (interactor1 == null)
                throw new ArgumentNullException("interactor1");
            if (interactor2 == null)
                throw new ArgumentNullException("interactor2");
            if (dbXrefs == null)
                throw new ArgumentNullException("dbXrefs");

            Confidence = confidence;
            DbXrefs = dbXrefs;
            InteractionType = interactionType;
            ExperimentType = experimentType;
        }

        public Interaction(IInteractor interactor1, IInteractor interactor2, double confidence, InteractionType interactionType = InteractionType.Unknown, ExperimentType experimentType = ExperimentType.Unknown)
            : this(interactor1, interactor2, confidence, Enumerable.Empty<DbXref>(), interactionType, experimentType) { }

        public Interaction(IInteractor interactor1, IInteractor interactor2, IEnumerable<DbXref> dbXrefs, InteractionType interactionType = InteractionType.Unknown, ExperimentType experimentType = ExperimentType.Unknown)
            : this(interactor1, interactor2, 0.0, dbXrefs, interactionType, experimentType) { }

        public Interaction(IInteractor interactor1, IInteractor interactor2, InteractionType interactionType = InteractionType.Unknown, ExperimentType experimentType = ExperimentType.Unknown)
            : this(interactor1, interactor2, 0.0, Enumerable.Empty<DbXref>(), interactionType, experimentType) { }
        
        #endregion

        #region ICloneable implementation

        /// <summary>
        /// Creates an exact copy of current relation.
        /// </summary>
        /// <returns>Interaction</returns>
        public Interaction Clone()
        {
            return new Interaction(Source, Target, Confidence, DbXrefs, InteractionType, ExperimentType);
        }

        /// <summary>
        /// Creates an exact copy of current relation as an object. 
        /// </summary>
        /// <returns>Interaction</returns>
        object ICloneable.Clone()
        {
            return Clone();
        }

        #endregion

        #region IEquatable<Interaction> implementation

        public bool Equals(Interaction other)
        {
            return Source.Equals(other.Source) && Target.Equals(other.Target) && InteractionType.Equals(other.InteractionType) && ExperimentType.Equals(other.ExperimentType);
        }

        #endregion

        #region Object overriden

        public override int GetHashCode()
        {
            return base.GetHashCode() ^ InteractionType.GetHashCode() ^ ExperimentType.GetHashCode();
        }

        public override bool Equals(object other)
        {
            if (other == null)
                throw new ArgumentNullException();

            if (!(other is Interaction))
                throw new InvalidCastException("The 'other' argument is not a Interaction object.");

            return Equals(other as Interaction);
        }

        public override string ToString()
        {
            return String.Format("{0}:{1}, {2}", base.ToString(), InteractionType, ExperimentType);
        }

        #endregion
    }
}
